package cemp.common.util;

import cemp.common.http.stockapi.response.HttpStockApiDataResponse;
import cemp.common.http.stockapi.response.HttpStockApiIsTradeResponse;
import cemp.redis.constant.RedisKey;
import cemp.redis.util.RedisUtils;
import cemp.util.StockHttpUtil;
import cn.hutool.core.util.NumberUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;

import static cemp.common.constant.StockCommonConstant.*;

/**
 * @author xshibai
 * @date 2025年09月29日 11:10
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class StockUtil {
    private final RedisUtils redisUtils;
    private final RestTemplate restTemplate;

    public BigDecimal getUpRate(BigDecimal begin,BigDecimal end ){
        BigDecimal result = BigDecimal.ZERO;
        //result = NumberUtil.div((NumberUtil.sub(end,begin)),new BigDecimal(begin),2, RoundingMode.HALF_UP );
        result = NumberUtil.div((NumberUtil.sub(end,begin).multiply(BigDecimal.valueOf(100))),begin,4, RoundingMode.HALF_UP );
        return result;
    }

//    public static void main(String[] args) {
//        StockUtil util = new StockUtil(null,null);
//        System.out.println(util.getUpRate("99.8","100.80"));
//        System.out.println(util.getUpRate("99.8","78.99"));
//        System.out.println("success");
//    }
    public boolean isNotWeekend(LocalDate date){
        return date.getDayOfWeek().getValue() <6;
    }

    public boolean isOpenLocal(LocalDate date){
        boolean isOpen = false;
        //先判断是否是周末
        if(isNotWeekend(date)){
            //判断是否是节假日
            String key = RedisKey.STOCK_ISOPEN.concat(String.valueOf(date.getYear()));
            try{
                boolean isFestival =  redisUtils.isHashMember(key,DateUtil.localDate2Str(date));
                if ( ! isFestival) {
                    isOpen = true;
                }else{
                    isOpen = (Boolean)redisUtils.hget(key,DateUtil.localDate2Str(date));
                }
            }catch (Exception e){
                e.printStackTrace();
                System.out.println(e.getMessage());
            }


        }
        return isOpen;
    }

    /**
     * 判断当天是否开盘
     * @param date
     * @return
     */
    public boolean isOpen(String date){
        boolean isOpen = true;
        try {
            LocalDate ldate = DateUtil.str2LocalDate(date);
            //先查询redis中有没有
            Object isOpenObj =  redisUtils.hget(RedisKey.STOCK_ISOPEN.concat(String.valueOf(ldate.getYear())),date);
            if(isOpenObj == null){

                //判断是否周末
                if(DateUtil.str2LocalDate(date).getDayOfWeek().getValue() > 5 ){
                    isOpen = false;
                }else{
                    String url = String.format("%s%s?token=%s&tradeDate=%s",STOCK_HOST,STOCK_IS_TRADEDAY,STOCK_TOKEN,date);
                    //调用api
                    ResponseEntity<HttpStockApiDataResponse<HttpStockApiIsTradeResponse>> response = StockHttpUtil.doGet(restTemplate,
                            url,
                            HttpMethod.GET,
                            new ParameterizedTypeReference<HttpStockApiDataResponse<HttpStockApiIsTradeResponse>>() {}
                    );
                    if(response != null){
                        if(((HttpStockApiIsTradeResponse)response.getBody().getData()).getIsTradeDate() == 0){
                            isOpen=  false;
                        }
                    }
                }
                redisUtils.hset(RedisKey.STOCK_ISOPEN.concat(String.valueOf(ldate.getYear())),date,isOpen);
            }else {
                isOpen =  (Boolean) isOpenObj;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }

        return isOpen;
    }
}
